package rest

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"math/rand"
	"net/http"
	"time"
)

type ByteBucket map[string][]byte

func NewByteBucket() ByteBucket {
	return make(ByteBucket)
}

func (b ByteBucket) CopyFrom(urlstr string) error {

	resp, err := http.Get(urlstr)

	if err != nil {
		return err
	}

	defer resp.Body.Close()
	text, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return err
	}

	err = json.Unmarshal(text, b)

	if err != nil {
		return err
	}

	return nil
}

func (b ByteBucket) Get(id string) (io.Reader, int, error) {

	data, ok := b[id]

	if !ok {
		return nil, 404, errors.New("resource not found")
	}

	return bytes.NewBuffer(data), 200, nil
}

func (b ByteBucket) Post(body io.Reader) (string, int, error) {

	id := time.Now().String() + string(rand.Int())

	data, err := ioutil.ReadAll(body)

	if err != nil {
		return id, 500, errors.New("couldn't read POST data")
	}

	b[id] = data

	return id, 201, nil
}

func (b ByteBucket) Put(id string, body io.Reader) (int, error) {

	data, err := ioutil.ReadAll(body)

	if err != nil {
		return 400, err
	}
	_, exists := b[id]

	b[id] = data

	if !exists {
		return 201, nil
	}

	return 200, nil
}

func (b ByteBucket) Delete(id string) (int, error) {

	delete(b, id)

	return 200, nil
}

func (b ByteBucket) List() (io.Reader, int, error) {

	text, err := json.Marshal(b)

	if err != nil {
		return nil, 500, err
	}

	return bytes.NewBuffer(text), 200, nil
}
